package com.topnav.mc.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.js.lib.result.Result;
import com.topnav.mc.admin.bean.OrgDeviceBean;
import com.topnav.mc.admin.dao.mapper.DeviceChannelMapper;
import com.topnav.mc.admin.entity.Organization;
import com.topnav.mc.admin.entity.bean.DeviceChannelBean;
import com.topnav.mc.admin.entity.param.DeviceChannelParam;
import com.topnav.mc.admin.security.PermissionGrade;
import com.topnav.mc.admin.service.IOrganizationService;
import com.topnav.mc.exception.ExceptionMsg;
import com.topnav.mc.uitls.PermissionGradeUtil;
import com.topnav.mc.uitls.ResultErrorUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 设备查询
 */
@Service
@Slf4j
public class DeviceQueryImpl {
    @Resource
    private PermissionGradeUtil pmGradeUtil;

    @Autowired
    private IOrganizationService organizationService;
    @Autowired
    private DeviceChannelMapper deviceChannelMapper;


    /**
     * 按关键字及状态查询
     * @param keyword
     * @param state 1 在线，-1 离线  0全部
     * @return
     */
    public Result searchBykeyword(String keyword,Integer state){
        List<OrgDeviceBean> resultDatas = new ArrayList<OrgDeviceBean>();
        //当前用户权限
        PermissionGrade permissionGrade = pmGradeUtil.getPmGrade();
        if (permissionGrade == null){
            return ResultErrorUtil.byExceptionMsg(ExceptionMsg.ERROR_AUTHENTICATION_FAILE);
        }
        //========= 通道列表查询 =======================
        QueryWrapper<DeviceChannelParam> wrapper = new QueryWrapper<>();
        //wrapper.and(wrapper1->wrapper1.eq("d.type",2).or().eq("d.type",3));
        //wrapper.and(wrapper1->wrapper1.eq("d.cate",2));
        if (permissionGrade.getPermissionLevel()==1 || permissionGrade.getPermissionLevel()==2){
            wrapper.eq("o.id",permissionGrade.getOrgId());
        }else if (permissionGrade.getPermissionLevel()==3 || permissionGrade.getPermissionLevel() == 4){
            wrapper.likeRight("o.path",permissionGrade.getOrgPath());
        }
        if (!StringUtils.isEmpty(keyword)){
            wrapper.and(
                    wrapper1->wrapper1.like("c.name",keyword)
                            .or().like("c.channel_code",keyword)
                            .or().like("d.name",keyword)
                            .or().like("d.code",keyword)
                            .or().like("d.shot_name",keyword)

            );
        }
        wrapper.eq("d.cate",2);
        wrapper.eq("c.`channel_type`",1);
        if (state == 1){
            wrapper.eq("d.online",1);
            //查在线的
            wrapper.and(
                    //有些执法传上来的通道status为0
                    wrapper1->wrapper1.and(wrapper2->wrapper2.eq("d.channel_count",1).eq("c.status",0))
                            .or(wrapper3->wrapper3.eq("c.status",1))
            );
        }else if (state == -1){
            wrapper.and(
                    wrapper1->wrapper1.eq("d.online",0).
                            or(wrapper2->wrapper2.eq("d.online",1).eq("c.status",0))
            );
        }
        List<DeviceChannelBean> channelBeanList =  deviceChannelMapper.findChannelInfo(wrapper);
        for(DeviceChannelBean deviceChannelBean : channelBeanList){
            if (!deviceChannelBean.getOnline()){
                deviceChannelBean.setStatus(0);
            }
        }

        // =================== 查询单位 =====================================================
        QueryWrapper<Organization> orgWrapper = new QueryWrapper();
        if (permissionGrade.getPermissionLevel()==1 || permissionGrade.getPermissionLevel()==2){
            orgWrapper.eq("id",permissionGrade.getOrgId());
        }else if (permissionGrade.getPermissionLevel()==3 || permissionGrade.getPermissionLevel() == 4){
            orgWrapper.likeRight("path",permissionGrade.getOrgPath());
        }else if (permissionGrade.getPermissionLevel()==8){
            orgWrapper.likeRight("path",permissionGrade.getOrgPath());
        }
        List<Organization> orgList = organizationService.list(orgWrapper);

        Map<String,Organization> orgMap = new HashMap<>();
        for(Organization organization : orgList){
            orgMap.put(organization.getId().toString(),organization);
        }
        Map<String,OrgDeviceBean> orgDeviceMap = new HashMap<>();
        Map<String,OrgStateCount> orgStateCountMap = new HashMap<>();

        for(DeviceChannelBean deviceChannelBean:channelBeanList){
/*            System.out.println(orgDeviceMap.toString());
            System.out.println(orgMap.toString());
            System.out.println(orgStateCountMap.toString());*/

            //生成设备通道统计数据
            this.genDeviceChannel(
                    resultDatas, //结果
                    deviceChannelBean, //通道
                    orgDeviceMap, //部门设备
                    orgMap, //部门
                    orgStateCountMap );
        }

        this.updateStateSum(orgStateCountMap,resultDatas);

        return Result.ok(resultDatas);
    }


    /**
     * 按关键字及状态查询
     * @param keyword
     * @param state 1 在线，-1 离线  0全部
     * @return
     */
    public Result FindAllDeviceDeep(String keyword, Integer state){
        //当前用户权限
        PermissionGrade permissionGrade = pmGradeUtil.getPmGrade();
        if (permissionGrade == null){
            return ResultErrorUtil.byExceptionMsg(ExceptionMsg.ERROR_AUTHENTICATION_FAILE);
        }
        QueryWrapper<Organization> orgWrapper = new QueryWrapper();
        if (permissionGrade.getPermissionLevel() == 1 || permissionGrade.getPermissionLevel() == 2){
            orgWrapper.eq("id",permissionGrade.getOrgId());
        }else if (permissionGrade.getPermissionLevel() == 3 || permissionGrade.getPermissionLevel() == 4){
            orgWrapper.likeRight("path",permissionGrade.getOrgPath());
        }
        orgWrapper.orderByAsc("path");
        List<Organization> organizations = organizationService.list(orgWrapper);
        //转MAP
        Map<String, Organization> orgMap = organizations.stream().collect(
                Collectors.toMap(Organization::getIdString, (p) -> p));

        //查询所有的设备
        QueryWrapper<DeviceChannelParam> deviceWrapper = new QueryWrapper<>();
        deviceWrapper.eq("d.cate",2);
        deviceWrapper.eq("c.channel_type",1);
        if (permissionGrade.getPermissionLevel() == 1){
            deviceWrapper.eq("d.user_id",permissionGrade.getUserId());
        }else if (permissionGrade.getPermissionLevel() == 2){
            orgWrapper.eq("d.org_id",permissionGrade.getOrgId());
        }else if (permissionGrade.getPermissionLevel() == 3 || permissionGrade.getPermissionLevel() == 4){
            orgWrapper.likeRight("o.path",permissionGrade.getOrgPath());
        }
        if (!StringUtils.isEmpty(keyword)){
            deviceWrapper.and(
                    wrapper1->wrapper1.like("d.name",keyword)
                            .or().like("c.channel_code",keyword)
                            .or().like("d.code",keyword)
            );
        }
        if (state == 1){
            deviceWrapper.eq("d.online",1);
            //查在线的
            deviceWrapper.and(
                    //有些执法传上来的通道status为0
                    wrapper1->wrapper1.and(wrapper2->wrapper2.eq("d.channel_count",1).eq("c.status",0))
                            .or(wrapper3->wrapper3.eq("c.status",1))
            );
        }else if (state == -1){
            deviceWrapper.and(
                    wrapper1->wrapper1.eq("d.online",0).
                            or(wrapper2->wrapper2.eq("d.online",1).eq("c.status",0))
            );
        }
        deviceWrapper.orderByAsc("c.id");
        List<DeviceChannelBean> channelBeanList =  deviceChannelMapper.findChannelInfo(deviceWrapper);
        for(DeviceChannelBean deviceChannelBean : channelBeanList){
            if (!deviceChannelBean.getOnline()){
                deviceChannelBean.setStatus(0);
            }
        }

        List<OrgDeviceBean> resultDatas = new ArrayList<OrgDeviceBean>();
        Map<String,OrgDeviceBean> orgDeviceMap = new HashMap<>();
        Map<String,OrgStateCount> orgStateCountMap = new HashMap<>();

        for(DeviceChannelBean deviceChannelBean:channelBeanList){
/*            System.out.println(orgDeviceMap.toString());
            System.out.println(orgMap.toString());
            System.out.println(orgStateCountMap.toString());*/

            //生成设备通道统计数据
            this.genDeviceChannel(
                    resultDatas, //结果
                    deviceChannelBean, //通道
                    orgDeviceMap, //部门设备
                    orgMap, //部门
                    orgStateCountMap );
        }

        this.updateStateSum(orgStateCountMap,resultDatas);

        return Result.ok(resultDatas);
    }

    /**
     * 生成新的设备和通道
     * @param listData 结果数据集
     * @param deviceChannelBean 通道数据
     * @param orgDeviceMap 单位设备map
     * @param orgMap 单位map
     * @return
     */
    private void genDeviceChannel(
            List<OrgDeviceBean> listData,
            DeviceChannelBean deviceChannelBean,
            Map<String,OrgDeviceBean> orgDeviceMap,
            Map<String,Organization> orgMap,
            Map<String,OrgStateCount> orgStateCountMap
    ){
        String key = null;
        OrgDeviceBean parent = null;
        //if (deviceChannelBean.getType() == 2){
        if (deviceChannelBean.getChannelCount() == 1){
            //执法仪, 没有下级的通道
            OrgDeviceBean bean = new OrgDeviceBean();
            key = "C-" + deviceChannelBean.getDeviceId().toString();
            bean.setId(key);
            bean.setDeviceType(deviceChannelBean.getType());
            bean.setTitle(deviceChannelBean.getDeviceName()==null?deviceChannelBean.getName():deviceChannelBean.getDeviceName());
            bean.setType("chn");
            //这是执法仪又设备的online为准
            bean.setOnline(deviceChannelBean.getOnline()==true?"true":"false");//deviceChannelBean.getStatus()==1?"1":"0");// ;
            bean.getArrt().put("deviceCode",deviceChannelBean.getDeviceCode());
            bean.getArrt().put("channelCode",deviceChannelBean.getChannelCode());
            bean.getArrt().put("deviceId",deviceChannelBean.getDeviceId());
            bean.getArrt().put("orgName",deviceChannelBean.getOrgName());
            bean.getArrt().put("orgCode",deviceChannelBean.getOrgCode());
            bean.getArrt().put("orgId",deviceChannelBean.getOrgId());
            bean.getArrt().put("devName",deviceChannelBean.getDeviceName());
            bean.getArrt().put("deviceName",deviceChannelBean.getDeviceName());
            bean.getArrt().put("userName",deviceChannelBean.getUserName());
            bean.getArrt().put("userCode",deviceChannelBean.getUserCode());
            bean.getArrt().put("direction","0°");
            bean.getArrt().put("speed","0.00");
            bean.getArrt().put("locate","");
            orgDeviceMap.put(key,bean);

            parent = this.getParentOrg(
                    listData,
                    deviceChannelBean.getPath(),
                    orgDeviceMap,
                    orgMap
            );
            if (parent == null){
                //没有上级单位
                this.addToList(listData,bean);
            }else{
                this.setChildren(parent,bean);
            }

            //更新单位的在线/总数统计
            updateOrgStateCount(orgStateCountMap,orgMap,deviceChannelBean.getPath(),deviceChannelBean.getStatus()==1?true:false);

            return;

        }else if (deviceChannelBean.getChannelCount() > 1){//(deviceChannelBean.getType() == 3){
            //有多个通道
            key = "D-" + deviceChannelBean.getDeviceId().toString();
            OrgDeviceBean deviceBean = (OrgDeviceBean)orgDeviceMap.get(key);
            if (deviceBean == null){
                deviceBean = new OrgDeviceBean();
                deviceBean.setId(key);
                deviceBean.setType("dev");
                deviceBean.setDeviceType(2);
                deviceBean.setTitle(deviceChannelBean.getDeviceName());
                deviceBean.setOnline("false");//deviceChannelBean.getStatus()==1?"true":"false");
                deviceBean.getArrt().put("deviceCode",deviceChannelBean.getDeviceCode());
                deviceBean.getArrt().put("deviceName",deviceChannelBean.getDeviceName());
                deviceBean.getArrt().put("deviceId",deviceChannelBean.getDeviceId());

                orgDeviceMap.put(key,deviceBean);
                parent = this.getParentOrg(listData,deviceChannelBean.getPath(),orgDeviceMap,orgMap);
                if (parent == null){
                    //没有上级单位
                    this.addToList(listData,deviceBean);
                }else{
                    this.setChildren(parent,deviceBean);
                }

                //更新设备的在线/总数统计
                updateDeviceStateCount(orgStateCountMap,key,deviceChannelBean.getStatus()==1?true:false);

                parent = deviceBean;
            }

            //通道
            OrgDeviceBean bean = new OrgDeviceBean();
            key = "C-" + deviceChannelBean.getId().toString();
            bean.setId(key);
            bean.setDeviceType(deviceChannelBean.getType());
            bean.setTitle(deviceChannelBean.getName()==null?deviceChannelBean.getChannelCode():deviceChannelBean.getName());
            bean.setType("chn");
            bean.setOnline(deviceChannelBean.getStatus().toString());
            bean.getArrt().put("code",deviceChannelBean.getChannelCode());
            bean.getArrt().put("deviceCode",deviceChannelBean.getDeviceCode());
            bean.getArrt().put("channelCode",deviceChannelBean.getChannelCode());
            bean.getArrt().put("deviceId",deviceChannelBean.getDeviceId());

            bean.getArrt().put("orgName",deviceChannelBean.getOrgName());
            bean.getArrt().put("orgCode",deviceChannelBean.getOrgCode());
            bean.getArrt().put("path",deviceChannelBean.getPath());
            bean.getArrt().put("orgId",deviceChannelBean.getOrgId());
            bean.getArrt().put("devName",deviceChannelBean.getDeviceName());
            bean.getArrt().put("deviceName",deviceChannelBean.getDeviceName());
            bean.getArrt().put("userName",deviceChannelBean.getUserName());
            bean.getArrt().put("userCode",deviceChannelBean.getUserCode());
            bean.getArrt().put("direction","0°");
            bean.getArrt().put("speed","0.00");
            bean.getArrt().put("locate","");

            orgDeviceMap.put(key,bean);
            this.setChildren(parent,bean);

            //更新单位的在线/总数统计
            updateOrgStateCount(orgStateCountMap,orgMap,deviceChannelBean.getPath(),deviceChannelBean.getStatus()==1?true:false);
        }

    }

    /**
     * 取设备的上级单位
     * @param listData 结果数据集
     * @param path  单位路径
     * @param orgDeviceMap  保存结果集MAP
     * @param orgMap 单位列表
     * @return
     */
    private OrgDeviceBean getParentOrg(
            List<OrgDeviceBean> listData,
            String path,
            Map<String,OrgDeviceBean> orgDeviceMap,
            Map<String,Organization> orgMap
            ){
        if (StringUtils.isEmpty(path)){
            return null;
        }
        OrgDeviceBean bean =null;
        //OrgDeviceBean firstBean =null;
        OrgDeviceBean parent = null;
        String key=null;
        String[] paths = path.split("/");
        boolean first=false;
        for(int i=0;i<paths.length;i++){
            key="O-" + paths[i].toString();
            bean = (OrgDeviceBean)orgDeviceMap.get(key);
            if (bean == null){
                Organization org = null;
                if ((org=orgMap.get(paths[i])) != null){
                    bean = new OrgDeviceBean();
                    bean.setTitle(org.getShortName());
                    //key = "O-" + paths[i].toString();
                    bean.setId(key);
                    bean.setType("org");
                    bean.setOnline("0");
                    bean.getArrt().put("orgCode",org.getCode());
                    bean.getArrt().put("path",org.getPath());
                    orgDeviceMap.put(key,bean);
                    if (parent != null){
                        this.setChildren(parent,bean);
                    }
                    parent = bean;
                }
            }else{
                parent = bean;
            }

            if (first == false && bean != null){
                this.addToList(listData,bean);
                first = true;
            }
/*            if (i==0 ){

            }*/
        }
        return bean;
    }

    /**
     * 加最上层的数据到list结果集中
     * @param listData
     * @param bean
     */
    private void addToList(List<OrgDeviceBean> listData,OrgDeviceBean bean){
        if (bean == null){return ; }

        boolean found = false;
        for(OrgDeviceBean orgDeviceBean : listData){
            if (orgDeviceBean.getId().equals(bean.getId())){
                found =true;
                break;
            }
        }
        if (!found)
            listData.add(bean);
    }



    /**
     * 设置子组件
     * @param parent
     * @param children
     */
    private void setChildren(OrgDeviceBean parent,OrgDeviceBean children){
        if (parent != null){
            if (parent.getChildren()==null){
                parent.setChildren(new ArrayList<>());
            }
            parent.getChildren().add(children);
        }
    }

    /**
     * 在线/总数状态汇总
     * @param map
     * @param resultData
     */
    private void updateStateSum(Map<String,OrgStateCount> map,List<OrgDeviceBean> resultData){
        OrgStateCount orgStateCount = null;
        for(OrgDeviceBean orgDeviceBean : resultData){
            orgStateCount = map.get(orgDeviceBean.getId());
            if (orgStateCount != null){
                orgDeviceBean.setTitle(orgDeviceBean.getTitle() + orgStateCount.getCountStr());
            }
            if (orgDeviceBean.getChildren() != null){
                this.updateStateSum(map,orgDeviceBean.getChildren());
            }

        }
    }

    /**
     * 更新设备的在线/总数统计
     * @param map
     * @param id
     * @param online
     */
    private void updateDeviceStateCount(Map<String,OrgStateCount> map,String id,boolean online){
        OrgStateCount orgStateCount = map.get(id);
        if (orgStateCount == null){
            orgStateCount = new OrgStateCount();
            map.put(id,orgStateCount);
        }
        orgStateCount.incAllCount();
        if (online==true){
            orgStateCount.incOnlineCount();
        }
    }


    /**
     * 更新单位的在线/总数统计
     * @param map
     * @param orgMap
     * @param path
     * @param online
     */
    private void updateOrgStateCount(Map<String,OrgStateCount> map,Map<String,Organization> orgMap,String path,boolean online){
        if (StringUtils.isEmpty(path)){
            return;
        }
        String[] paths = path.split("/");
        String id=null;
        for(int i=paths.length-1;i>=0;i--){
            id="O-"+paths[i];
            OrgStateCount orgStateCount = map.get(id);
            if (orgStateCount == null){
                orgStateCount = new OrgStateCount();
                map.put(id,orgStateCount);
            }
            orgStateCount.incAllCount();
            if (online==true){
                orgStateCount.incOnlineCount();
            }
        }


    }
    /**
     * 部门设备在线/总数统计类
     */
    @Data
    public static class OrgStateCount{
        private Integer onlineCount=0;
        private Integer allCount=0;

        public void incAllCount(){
            allCount++;
        }

        public void incOnlineCount(){
            onlineCount++;
        }

        public String getCountStr(){
            return "("+onlineCount + "/" + allCount + ")";
        }
    }


}
